﻿package com.dLibs.video
{
	import com.dLibs.events.Events;
	
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.NetStatusEvent;
	import flash.media.SoundTransform;
	import flash.media.Video;
	import flash.net.NetConnection;
	import flash.net.NetStream;
	import flash.system.System;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	
	public class videoPlayer extends MovieClip
	{
		/* @ Variables				____________________________________________*/
		
		private var _videoWidth				:uint;
		private var _videoHeight			:uint;
		private var _videoURL				:String;
		private var _nvideo					:Video;
		private var _videoStarted			:Boolean;
		private var _videoBuffer			:uint;
		private var _finishFunct			:Function;
		private var nets					:NetStream;
		private var netc					:NetConnection;
		private var soundVolume				:Number;
		private var pastVolume				:Number;
		private var sndTransf				:SoundTransform;
		private var videoPlaying			:Boolean;
		private var videoStoped				:Boolean;
		private var actTime					:uint;
		private var	uintDurtion				:uint; 
		private var seekProgress			:MovieClip;
		private var seekLoader				:MovieClip;
		private var seekWidth				:Number;
		
		/* @ Control Clips			____________________________________________*/
		
		private var playpauseBt				:MovieClip;
		private var bufferClip				:MovieClip;
		private var muteButtom				:MovieClip;
		private var durTime					:TextField;
		private var netsMetaData			:Object;
		
		/* @ Constructor			____________________________________________*/
		
		public function videoPlayer(videoURL:String,videoWidth:uint, videoHeight:uint, videoStarted:Boolean = true, videoBuffer:uint = 10):void
		{
			_videoURL			= videoURL;
			_videoWidth 		= videoWidth;
			_videoHeight 		= videoHeight;
			_videoBuffer		= videoBuffer;
			_videoStarted		= videoStarted;
			
			netsMetaData		= new Object();
			soundVolume			= 1;
			
			_nvideo 			= new Video(_videoWidth, _videoHeight);
			
			netc = new NetConnection();
			netc.connect(null);
			
			nets = new NetStream(netc);
			nets.client = netsMetaData;
			netsMetaData.onMetaData = metaObject;
			nets.addEventListener(NetStatusEvent.NET_STATUS, onVideoEvent);
			
			sndTransf = new SoundTransform(soundVolume);			
			
			nets.soundTransform = sndTransf;
			nets.bufferTime = _videoBuffer;
			if ( _videoURL != "" ) nets.play(_videoURL);
			
			if ( !_videoStarted ) 
			{
				nets.pause();
				videoPlaying = false;
			}
			else 
			{
				videoPlaying = true;
			}
			
			
			_nvideo.attachNetStream(nets);
			addChild(_nvideo);
			
			addEventListener(Event.ENTER_FRAME, controlTime);
			addEventListener(Event.REMOVED_FROM_STAGE, removeAllData);
		}
		
		public function set newVideo(url:String):void
		{
			_nvideo = new Video(_videoWidth, _videoHeight);
			nets.play(url);
		}
		
		/* @ add Controlls: Play	____________________________________________*/
		
		public function set addPlayPause(pButton:MovieClip):void
		{
			playpauseBt = new MovieClip();
			playpauseBt = pButton;
			playpauseBt.buttonMode = true;
			playpauseBt.mouseChildren = false;
			playpauseBt.addEventListener(MouseEvent.CLICK, playPauseVideo);
		}
		
		private function playPauseVideo(m:MouseEvent):void
		{
			if ( !videoStoped )
			{
				videoStoped = false;
				
				if ( videoPlaying ) 
				{
					nets.pause();
					videoPlaying = false;
				}
				else
				{
					nets.resume();
					videoPlaying = true;
				}
			}
			else
			{
				videoStoped = true;
				videoPlaying = true;
				nets.play(_videoURL);
			}
		}
		
		/* @ add Controlls: Buffer	____________________________________________*/
		
		public function set addBuffer(bClip:MovieClip):void
		{
			bufferClip = new MovieClip();
			bufferClip = bClip;
			bufferClip.visible = false;
		}
		
		/* @ add Controlls: Mute	____________________________________________*/
		
		public function set addMuteSound(muteClip:MovieClip):void
		{
			muteButtom = new MovieClip();
			muteButtom = muteClip;
			muteButtom.buttonMode = true;
			muteButtom.mouseChildren = false;
			muteButtom.addEventListener(MouseEvent.CLICK, muteSound);
		}
		
		private function muteSound(m:MouseEvent):void
		{
			if ( soundVolume > 0 )
			{
				pastVolume = soundVolume;
				soundVolume = 0;
				sndTransf = new SoundTransform(soundVolume);
				nets.soundTransform = sndTransf;
			}
			else
			{
				soundVolume = pastVolume;
				sndTransf = new SoundTransform(soundVolume);
				nets.soundTransform = sndTransf;
			}			
		}
		
		/* @ add Controlls: Duration time	____________________________________________*/
		
		private function metaObject(o:Object):void
		{
			uintDurtion = o.duration;
		}
		
		private function controlTime(e:Event):void
		{
			if ( durTime != null )
			{
				actTime = nets.time;
				durTime.autoSize = TextFieldAutoSize.RIGHT;
				// @ Creatint the variables
				var tminute:String;
				var tsecond:String;
				var aminute:String;
				var asecond:String;
				// @ Actual Minute
				if ( actTime/60 < 10 ) { aminute = String("0" + int(actTime/60)); }
				else { aminute = String(int(actTime/60)); }
				// @ Actual Second
				if ( actTime%60 < 10 ) { asecond = String("0" + int(actTime%60)); }
				else { asecond = String(int(actTime%60)); }
				// @ Total Minute
				if ( uintDurtion/60 < 10 ) { tminute = String("0" + int(uintDurtion/60)); }
				else { tminute = String(int(uintDurtion/60)); }
				// @ Total Second
				if ( uintDurtion%60 < 10 ) { tsecond = String("0" + int(uintDurtion%60)); }
				else { tsecond = String(int(uintDurtion%60)); }
				// @ Construct the Time
				durTime.text = String(aminute + ":" + asecond + " / " + tminute + ":" + tsecond);
			}
			
			if ( seekProgress != null )
			{
				seekProgress.scaleX = ( nets.time / uintDurtion );
			}
			
			if ( seekLoader != null )
			{
				seekLoader.scaleX = ( nets.bytesLoaded / nets.bytesTotal );
			}
		}
		
		public function set addDuration(duration:TextField):void
		{
			durTime = new TextField();
			durTime = duration;
		}
		
		/* @ add Controlls: Close	____________________________________________*/
		
		public function set addSeek(seekClips:Object):void
		{
			if ( seekClips.progress != undefined )
			{
				seekProgress 	= new MovieClip();
				seekProgress 	= seekClips.progress;
				seekWidth 		= seekProgress.width;
				seekProgress.addEventListener(MouseEvent.CLICK, seekTo);
			}
			
			if ( seekClips.loader != undefined )
			{
				seekLoader 	= new MovieClip();
				seekLoader 	= seekClips.loader;
				seekWidth 	= seekLoader.width;
				seekLoader.addEventListener(MouseEvent.CLICK, seekTo);
			}
		}
		
		private function seekTo(m:MouseEvent):void
		{
			if ( seekLoader != null && m.currentTarget.mouseX < seekLoader.width )
			{
				var videoPercent:Number = (( m.currentTarget.mouseX ) / seekWidth);
				nets.seek(uintDurtion * videoPercent);
			}
		}
		
		/* @ add Controlls: Close	____________________________________________*/
		
		public function close():void
		{
			nets.seek(0);
			nets.close();
		}
		
		/* @ Events of video		____________________________________________*/
		
		private function onVideoEvent(stat:Object):void
		{			
			if ( stat.info.code == "NetStream.Play.Start" )
			{
				dispatchEvent(new Events(Events.VIDEO_START));
			}
			if ( stat.info.code == "NetStream.Buffer.Empty" )
			{
				if (bufferClip != null) bufferClip.visible = true;
				dispatchEvent(new Events(Events.VIDEO_EMPTY));
			}
			if ( stat.info.code == "NetStream.Buffer.Full" )
			{
				if (bufferClip != null) bufferClip.visible = false;
				dispatchEvent(new Events(Events.VIDEO_FULL));
			}
			if ( stat.info.code == "NetStream.Play.Stop" )
			{
				if (bufferClip != null) 	bufferClip.visible = false;
				if (_finishFunct != null) 	_finishFunct();
				dispatchEvent(new Events(Events.VIDEO_STOP));
				videoPlaying = false;
				videoStoped = true;
			}
		}
		
		/* Remove all data, loaders, parameters and others */
		
		private function removeAllData(e:Event):void
		{
			nets.close();
			nets.removeEventListener(NetStatusEvent.NET_STATUS, onVideoEvent);
			nets = null;
			
			netc.close();
			netc = null;
			
			_nvideo.clear();
			addChild(_nvideo);
			
			removeEventListener(Event.ENTER_FRAME, controlTime);
			removeEventListener(Event.REMOVED_FROM_STAGE, removeAllData);
			
			for ( var endi:uint = 0; endi < 20; endi++ ) { System.gc(); }
		}
		
		/* @ END OF CODE			____________________________________________*/		
	}
}